
/**
  * @file simple explain
  * < thread policy >
  * 
  * Copyright (c) by <lid/>
  * @author jingwei.guan@hotmail.com
  * modify history:
  * date           version     author         content
  * 09/17/2010      0.0.1       lid            create
  * 11/03/2010      0.0.2       lid            add another thread solution
  *
  * eg1: ---------------- derived version ----------------
  *	class Foo : public threadmutex::ThreadModel<>
  *	{
  *	public:
  *		void test
  *		{
  *			Lock lock;
  *		}
  *	}
  *
  * eg2: ---------------- derived version ----------------
  *	template <
  *		typename MutexModel = threadmutex::NoMutex,
  *		template<typename,template<typename> class = threadmutex::ClassLock> class ThreadingModel = threadmutex::ThreadModel
  *	>
  *	class Foo : public ThreadingModel<MutexModel>
  *	{
  *	public:
  *		void test
  *		{
  *			Lock lock;
  *		}
  *	}
  * 
  *
  * eg3: ---------------- not derived version ----------------
  *
  *	class Test
  *	{
  *	public:
  *		typedef threadmutex::FastClassLock<MTest1,threadmutex::CriticalSectionMutex>::lock Lock;
  *		void test()
  *		{
  *			Lock lock;
  *		}
  *	};
  *
  *
 */

#ifndef _97fa8336_d447_447d_a42d_def12878fc10__THREADMODEL_H__
#define _97fa8336_d447_447d_a42d_def12878fc10__THREADMODEL_H__

#include <windows.h>

namespace threadmutex
{

	////////////////////////////////////////////////////////////////////////// mutex policy
	class NoMutex
	{
	public:
		NoMutex(){}
		void lock(){}
		void unlock(){}
	private:
		NoMutex(const NoMutex&);
		NoMutex& operator=(const NoMutex&);
	};

	class CriticalSectionMutex
	{
	public:
		CriticalSectionMutex(){
			::InitializeCriticalSection(&cs_);
		}
		~CriticalSectionMutex(){
			::DeleteCriticalSection(&cs_);
		}
		void lock(){
			::EnterCriticalSection(&cs_);
		}
		void unlock(){
			::LeaveCriticalSection(&cs_);
		}
	private:
		CriticalSectionMutex(const CriticalSectionMutex&);
		CriticalSectionMutex& operator=(const CriticalSectionMutex&);
		CRITICAL_SECTION cs_;
	};


	////////////////////////////////////////////////////////////////////////// derived version
	template<typename T>
	class ClassLock
	{
	public:
		class lock
		{
			lock(const lock&);
			lock& operator=(const lock&);
		public:
			lock()
			{
				mutex.lock();
			}
			~lock()
			{
				mutex.unlock();
			}
		};
	private:
		ClassLock(const ClassLock&);
		ClassLock& operator=(const ClassLock&);
		static T mutex;
	};

	template<typename T> T ClassLock<T>::mutex;


	template<typename MutexPocily = CriticalSectionMutex,template<typename> class LockPolicy = ClassLock>
	class ThreadModel
	{
	public:
		typedef typename LockPolicy<MutexPocily>::lock Lock;
	};



	////////////////////////////////////////////////////////////////////////// not derived version
	template<typename Host,typename MutexPocily = CriticalSectionMutex>
	class FastClassLock
	{
	public:
		typedef Host wind_type;

		class lock
		{
			lock(const lock&);
			lock& operator=(const lock&);
		public:
			lock()
			{
				mutex.lock();
			}
			~lock()
			{
				mutex.unlock();
			}
		};
	private:
		FastClassLock(const FastClassLock&);
		FastClassLock& operator=(const FastClassLock&);
		static MutexPocily mutex;
		
	};

	template<typename Host,typename MutexPocily> 
	MutexPocily FastClassLock<Host,MutexPocily>::mutex;

}

#endif //_97fa8336_d447_447d_a42d_def12878fc10__THREADMODEL_H__